/*
 * @Description: 
 * @Author: liyuhao
 * @Date: 2021-08-14 15:59:32
 * @LastEditors: liyuhao
 * @LastEditTime: 2021-09-18 11:09:59
 */
import React, {useState} from 'react'
import {Image, message, Modal, Upload} from 'antd'
import {UploadProps} from 'antd/lib/upload'
import {BaseButtonProps} from 'antd/lib/button/button'
import {LoadingOutlined, PlusOutlined} from '@ant-design/icons'
import SpinButton from '@/components/SpinButton'
import {getImage} from "@/services/resource/public.ts";

interface UploadFileProps extends Pick<UploadProps, 'listType' | 'disabled' | 'multiple' | 'itemRender' | 'showUploadList'> {
    // folder: string;
    isImg?: boolean
    fileList?: any[]
    onChange?: (files?: any[]) => void
    acceptType?: string[]
    typeErrorMsg?: string
    buttonType?: BaseButtonProps['type']
    buttonText?: string
    customButton?: ((loading: boolean) => JSX.Element) | null // 自定按钮
    max?: number // 文件最大数目 默认为1 目前listType为picture-card时才奇效
    maxFileNum?: number // 文件最大数目 只控制上传文件数量 不控制上传按钮 到达上限后继续上传会覆盖第一个文件 0无效
    style?: React.CSSProperties
    maxSize?: number // 文件最大体积 单位Mb
    withoutName?: boolean // 文件上传后是否需要文件名 将调用不同的接口
    service: (value?: any) => Promise<any>
    formatFilePath?: (str?: string) => string | null // 处理文件路径 用于展示文件
    onPreview?: (file: any) => void
}

const UploadButton = (loading: boolean) => (
    <div>
        {loading ? <LoadingOutlined/> : <PlusOutlined/>}
        <div style={{marginTop: 8}}>上传</div>
    </div>
)

// 默认图片预览方式
const defaultImgPreview = (file: any) => {
    Modal.info({
        width: 564,
        icon: null,
        okText: '关闭',
        content: <div style={{textAlign: 'center'}}><Image src={file.url} preview={false} width={500}/></div>
    })
}

const Uploader: React.FC<UploadFileProps> = props => {
    const {
        isImg = true,
        fileList = [],
        disabled,
        onChange,
        acceptType,
        typeErrorMsg,
        listType,
        multiple,
        itemRender,
        showUploadList = true,
        buttonType,
        buttonText = '上传附件',
        customButton = UploadButton,
        max = 1,
        maxFileNum,
        style,
        maxSize,
        service,
        formatFilePath = getImage,
        onPreview
    } = props || {}
    const [loading, setLoading] = useState(false)

    const handleRemove = (file: any) => {
        const files = fileList?.filter((v: any) => v.uid !== file.uid)
        onChange && onChange(files)
    }
    const handleBeforeUpload = (file: any) => {
        console.log('上传file', file)
        const type = file.name.split('.')[file.name.split('.').length - 1]
        if (acceptType && !acceptType.includes(type?.toLocaleLowerCase())) {
            message.error(typeErrorMsg || '不支持上传此格式文件')
            return false
        }

        if (maxSize) {
            const fileSize = file.size / 1024 / 1024
            console.log('fileSize', fileSize, file.size)
            if (fileSize > maxSize) {
                message.error(`文件大小不能大于${maxSize}Mb`)
                return false
            }
        }

        const formData = new FormData()
        // formData.append('folder', folder)
        formData.append('file', file)
        !loading && setLoading(true)
        service(formData)
            .then(res => {
                if (res) {
                    const name = res?.fileName
                    const url = res?.filePath
                    const type = name.split('.').pop()
                    const fileInfo = {
                        type,
                        uid: parseInt(`${Math.random() * 10000}`),
                        thumbUrl: url,
                        url,
                        name,
                        size: res?.size || file.size
                    }
                    if (onChange) {
                        let newFileList = [...fileList, fileInfo]
                        const length = newFileList.length
                        if (maxFileNum && length > maxFileNum) {
                            newFileList.splice(0, length - maxFileNum)
                        }
                        onChange(newFileList)
                    }
                }
            })
            .finally(() => setLoading(false))
        return false
    }

    return (
        <div style={style}>
            <Upload
                onRemove={handleRemove}
                fileList={formatFilePath ? fileList.map((v: any) => ({
                    ...v,
                    url: formatFilePath(v.url),
                    thumbUrl: formatFilePath(v.thumbUrl)
                })) : fileList}
                multiple={multiple}
                itemRender={itemRender}
                beforeUpload={handleBeforeUpload}
                listType={listType}
                showUploadList={showUploadList}
                disabled={disabled}
                onPreview={onPreview ? onPreview : isImg ? defaultImgPreview : undefined}
            >
                {!disabled && (
                    fileList.length >= max && listType === 'picture-card'
                        ? null
                        : customButton
                            ? customButton(loading)
                            : <SpinButton type={buttonType} loading={loading} disabled={loading}>{buttonText}</SpinButton>
                )}
            </Upload>
        </div>
    )
}
export default Uploader
